Nowadays, a computing system usually includes objects of various forms, such as events, files, I/O completion ports, directories, devices, drivers, stream file objects, etc. Different components in the computing system may try to recognize an object based on attributes associated with the object. A component can be an application program or a unit of an operating system. For example, if the object is a file, a word processing program in the computing system may use the file path to identify the file. The components then may want to understand what data or metadata are associated with the object. For example, the exemplary file may be associated with various metadata such as policies. The policies can include “not allowing the file to run if it is an executable,” “running the file in the same directory,” “giving the file certain privileges,” “allowing the file to run at certain times of the day,” or “running the file as a different user,” etc. Data such as the policies enable a component to understand what actions the component can perform with the object.
Data such as the exemplary policies mentioned above may be supplied by different sources, i.e., data providers. An object may have many data providers supplying data for the object and the data may change from time to time. Operationally, a computing system may cache the data to improve system performance. A version number, also called a sequence number, may be attached to the data supplied by a specific data provider. Whenever the data supplied by the data provider changes, the sequence number changes, e.g., in increments to indicate a new version of the data. The sequence number may be cached along with the data. The cached sequence number can be used to validate whether the data in the cache is the current version of the data. For example, if the cached sequence number indicates that the cached data is a version 5, and the data provider currently has an updated version, e.g., version 7 of the data, then the cached data is invalid. The computing system can then request the data provider to supply the current version of the data. Such use of the sequence number saves computing time, because the computing system does not have to traverse all objects that have cached the data supplied by the data provider to invalidate the outdated data. Invalidation occurs only when the cached data for the object is requested.
However, the use of sequence numbers may consume too much memory space. For example, the exemplary file object may have thirty data providers supplying data for the file object. The thirty cached sequence numbers consume a specific amount of cache space. A computing system may contain thousands of such objects. Their cached sequence numbers may thus use a large amount of cache space that can otherwise be used to cache more data. Therefore, it is desirable to reduce the size of a sequence number so as to reduce the cache space the sequence number consumes and, therefore, to enable more data to be cached for an object.
More importantly, in recent years, spoofing and impersonation software attacks have increased substantially. Such attacks may force a data provider to update its data in such a frequency that the associated sequence number rolls over. For instance, assuming that the cached sequence number is of version 5. Under a roll-over attack, the sequence number associated with the data provider may be updated so many times that it returns to version 5. As a result, the computing system erroneously assumes that the data supplied by the provider has not been changed, since the cached sequence number is the same as the sequence number that is currently associated with the data provider. Therefore, it is desirable to provide a mechanism to prevent such roll-over attacks.